# To change this template, choose Tools | Templates
# and open the template in the editor.

import sys

import unittest
import threading
import time
from gameserver import server

from gameserver.service.exceptions.ttypes import *
from gameserver.service import GameService

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

class  ServerTestCase(unittest.TestCase):
    def setUp(self):
        self.transport = TSocket.TSocket('localhost', 11111)
        self.transport = TTransport.TBufferedTransport(self.transport)
        self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport)
        self.client = GameService.Client(self.protocol)
        self.transport.open()
        self.event = list()
        
    def tearDown(self):
        self.transport.close()
    
    #Test game stop
    def test_65(self):
        self.assertTrue(self.client.stop_game(1), "Game not stopped")
    #Test wait for game start (2 clients waiting)
    def test_60(self):
        ttransport = TSocket.TSocket('localhost', 11111)
        ttransport = TTransport.TBufferedTransport(ttransport)
        tprotocol = TBinaryProtocol.TBinaryProtocol(ttransport)
        tclient = GameService.Client(tprotocol)
        ttransport.open()

        ttransport1 = TSocket.TSocket('localhost', 11111)
        ttransport1 = TTransport.TBufferedTransport(ttransport1)
        tprotocol1 = TBinaryProtocol.TBinaryProtocol(ttransport1)
        tclient1 = GameService.Client(tprotocol1)
        ttransport1.open()

        self.waitEvent = threading.Event()

        tthread1 = threading.Thread(target = self.client_wait, args=(1,2))
        tthread1.start()
 
        tthread2 = threading.Thread(target = self.client_wait, args=(2,2,tclient1))
        tthread2.start()

        tclient.start_game(1)
        ttransport.close()
        ttransport1.close()
        self.waitEvent.wait()
        self.assertEqual(self.event[0].type, GameService.EventType.GAME_START, 'Wrong event type')
        self.assertEqual(self.event[0].iword, 'First word', 'Wrong initial word')
        self.assertEqual(self.event[1].type, GameService.EventType.GAME_START, 'Wrong event type')
        self.assertEqual(self.event[1].iword, 'First word', 'Wrong initial word')

    #Test admin checking at stop
    def test_75(self):
        self.assertRaises(AccessViolation, self.client.stop_game, 2)
    #Test game start
    def test_70(self):
       self.assertEqual(self.client.start_game(1), 'First word', "Game not started")
    #Test admin checking at start
    def test_50(self):
        self.assertRaises(AccessViolation, self.client.start_game, 2)
    # Test registration maximum
    def test_40(self):
        self.assertRaises(RegistrationError, self.client.register_user, 3)
    # Test duplicate user login
    def test_30(self):
        self.assertRaises(RegistrationError, self.client.register_user, 1)
    # Test waiting
    def test_25(self):
        self.client.register_user(2)

        event = self.client.wait_for_event(2)
        self.assertEqual(event.type, GameService.EventType.USER_REGISTERED, 'Wrong event type')
        self.assertEqual(event.id, 1, 'Wrong user id')

        event = self.client.wait_for_event(2)
        self.assertEqual(event.type, GameService.EventType.USER_REGISTERED, 'Wrong event type')
        self.assertEqual(event.id, 2, 'Wrong user id')

        event = self.client.wait_for_event(1)
        self.assertEqual(event.type, GameService.EventType.USER_REGISTERED, 'Wrong event type')
        self.assertEqual(event.id, 1, 'Wrong user id')

        event = self.client.wait_for_event(1)
        self.assertEqual(event.type, GameService.EventType.USER_REGISTERED, 'Wrong event type')
        self.assertEqual(event.id, 2, 'Wrong user id')
    # Test user registration
    def test_20(self):
        self.assertTrue(self.client.register_user(1), "User not registered")
    # Test ping
    def test_10(self):
        self.assertTrue(self.client.ping(), "Ping failed")

    def client_wait(self, id, count, client = None):
        if not client:
            client = self.client
        self.event.append(client.wait_for_event(id))
        if len(self.event) == count:
            self.waitEvent.set()
            
server_thread = threading.Thread(target=server.start, args=(1,))
server_thread.start()

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(ServerTestCase)
    unittest.TextTestRunner(verbosity=2).run(suite)

